#include "message_sync_impl.h"

#include <core/QbLogger.h>
#include <core/sharedata/login_data.h>
#include <core/observer/message_observer.h>

namespace qb {
CMessageSyncImpl::CMessageSyncImpl()
    : m_critSect(*CriticalSectionWrapper::CreateCriticalSection()),
      m_observerDipatch(NULL) {}

CMessageSyncImpl::~CMessageSyncImpl() { delete &m_critSect; }

STDMETHODIMP_(int32_t) CMessageSyncImpl::Create(THIS_) {
  m_pusher = new MessagePusher(this);
  return 1;
}

STDMETHODIMP_(int32_t) CMessageSyncImpl::Destory(THIS_) {
  ////////////////////////////////////////////////////////////////////////////
  // remark1: 销毁动作必须在主线程中完成, 简化多线程管理逻辑
  // remark2: 这里认为模块的销毁时机一定是在所有调用此模块的子线程结束后
  ////////////////////////////////////////////////////////////////////////////

  // 清空观察者
  RemoveObserver<IMessageSyncObserver>(m_observersTUS);
  RemoveObserver<IMessageSyncObserver>(m_observersTS);
  delete m_pusher;
  return 0;
}

STDMETHODIMP_(int32_t)
CMessageSyncImpl::PushMessage(THIS_ const char* buff, uint32_t bytes,
                              uint32_t flag /*= 0*/, void* tag /*= NULL*/) {
  //	return m_message_sync_jni.PushMessage(buff, bytes, flag, tag);
  m_observerDipatch->PushMessage(buff, bytes, flag, tag);

  return 0;
}

STDMETHODIMP_(int32_t)
CMessageSyncImpl::RegisterMessageObserverTUS(
    THIS_ IMessageSyncObserver* observer) {
  int32_t nRet =
      RegisterObserver<IMessageSyncObserver>(observer, m_observersTUS);
  if (-1 == nRet) {
    log_warning("already enabled");
  }

  return nRet;
}

STDMETHODIMP_(int32_t)
CMessageSyncImpl::DeRegisterMessageObserverTUS(
    THIS_ IMessageSyncObserver* observer) {
  int32_t nRet =
      DeRegisterObserver<IMessageSyncObserver>(observer, m_observersTUS);
  if (-1 == nRet) {
    log_warning("already disabled");
  }

  return nRet;
}

STDMETHODIMP_(int32_t)
CMessageSyncImpl::RegisterMessageObserverTS(
    THIS_ IMessageSyncObserver* observer) {
  // 为确保线程安全, 此处枷锁
  CriticalSectionScoped cs(&m_critSect);

  int32_t nRet =
      RegisterObserver<IMessageSyncObserver>(observer, m_observersTS);
  if (-1 == nRet) {
    log_warning("already enabled");
  }

  return nRet;
}

STDMETHODIMP_(int32_t)
CMessageSyncImpl::DeRegisterMessageObserverTS(
    THIS_ IMessageSyncObserver* observer) {
  // 为确保线程安全, 此处枷锁
  CriticalSectionScoped cs(&m_critSect);

  int32_t nRet =
      DeRegisterObserver<IMessageSyncObserver>(observer, m_observersTS);
  if (-1 == nRet) {
    log_warning("already disabled");
  }

  return nRet;
}

STDMETHODIMP_(int32_t)
CMessageSyncImpl::RegisterMessageDispatchObserver(
    THIS_ IMessageDispatchObserver* observer) {
  CriticalSectionScoped cs(&m_critSect);

  m_observerDipatch = observer;

  return 0;
}

STDMETHODIMP_(int32_t)
CMessageSyncImpl::DeRegisterMessageDispatchObserver(
    THIS_ IMessageDispatchObserver* observer) {
  CriticalSectionScoped cs(&m_critSect);

  if (m_observerDipatch == observer) {
    m_observerDipatch = NULL;
  }

  return 0;
}

STDMETHODIMP_(int32_t)
CMessageSyncImpl::DispatchMessage(THIS_ const char* buff, uint32_t bytes,
                                  uint32_t flag, void* tag) {
  // 通知非线程安全观察者
  {
    if (kLoginConnect == flag) {
      int32_t* status = (int32_t*)tag;
      BList<IMessageSyncObserver*>::iterator iter_ts = m_observersTUS.begin();
      for_each_list(m_observersTUS, iter_ts,
                    (iter_ts++)->first->OnNetStatus(*status));
    } else {
      BList<IMessageSyncObserver*>::iterator iter_ts = m_observersTUS.begin();
      for_each_list(m_observersTUS, iter_ts,
                    (iter_ts++)->first->OnNetData((char*)buff, bytes));
    }
  }

  // 通知线程安全观察者
  {
    // 此处枷锁,容易造成死锁的调用回路
    // case1:
    // 观察者在"OnReceive"处理中调用了模态窗口,导致此处理锁资源在模块窗口销毁之前一直不能释放,
    //        若后面有其他调用RegisterMessageObserverTS/DeRegisterMessageObserverTS时,死锁
    // case2:
    // 观察者在"OnReceive"处理中调用或间接调用了RegisterMessageObserverTS/DeRegisterMessageObserverTS,导致死锁产生
    CriticalSectionScoped cs(&m_critSect);

    if (kLoginConnect == flag) {
      int32_t* status = (int32_t*)tag;
      BList<IMessageSyncObserver*>::iterator iter_tus = m_observersTS.begin();
      for_each_list(m_observersTS, iter_tus,
                    (iter_tus++)->first->OnNetStatus(*status));
    } else {
      BList<IMessageSyncObserver*>::iterator iter_tus = m_observersTS.begin();
      for_each_list(m_observersTS, iter_tus,
                    (iter_tus++)->first->OnNetData((char*)buff, bytes));
    }
  }

  return 0;
}
}  // namespace qb
